package com.ncmmall.mall.controller.business.merchant;

import com.ncmmall.application.business.merchant.MerchantApplication;
import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.lang.ArithUtils;
import com.feijin.commons.securitys.MD5HashUtils;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.merchant.MerchantGoodsChannel;
import com.ncmmall.domain.business.merchant.QMerchantGoodsChannel;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商家管理
 *
 * @author linxs
 * @date 2019-06-26 20:24
 */
@Controller
@RequestMapping(value = "/mall/merchant")
public class MerchantController {

    private static final Logger log = LoggerFactory.getLogger(MerchantController.class);

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private MerchantApplication merchantApplication;

    @Autowired
    private OperationLogApplication logApplication;


    /**
     * 分页条件筛选
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, QueryPageRequest pageRequest, WebUser merchant) {

        Map<String, Object> params = new HashMap<>();
        String hql = builderSQL("select u from WebUser u where u.role.name = 'MERCHANT' ", params, merchant);
        QueryPage<WebUser> page = queryChannelService.findPage(hql, pageRequest.setParams(params), WebUser.class);

        for (WebUser user : page.getResult()) {
            user.setGoodsNumber(queryChannelService.selectCount("select count(1) from mall_goods where merchant_id = :id and status = 3 ", ImmutableMap.of("id", user.getId())));
            double payAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.payStatus = 1 and o.merchant_id = :id ", ImmutableMap.of("id", user.getId()));
            double shoppingCardMoney = queryChannelService.selectSum("select ifnull(sum(o.shoppingCardMoney),0) from mall_order o where o.payStatus = 1 and o.merchant_id = :id ", ImmutableMap.of("id", user.getId()));
            user.setTotalOrderAmount(ArithUtils.add(payAmount, shoppingCardMoney));
        }

        model.addAttribute("page", page).addAttribute("params", merchant);

        return "mall/merchant/list";
    }

    /**
     * 查看商家详情
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);
        model.addAttribute("merchant", merchant).addAttribute("channels", queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(id), MerchantGoodsChannel.class));

        return "mall/merchant/detail";
    }

    /**
     * 添加商家
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    private String create(Model model) {

        model.addAttribute("merchant", new WebUser())
                .addAttribute("channels", queryChannelService.findAll(QGoodsChannel.goodsChannel.status.eq(1).and(QGoodsChannel.goodsChannel.level.eq(1).and(QGoodsChannel.goodsChannel.deleteStatus.eq(0))), GoodsChannel.class))
                .addAttribute("_method", "POST");

        return "mall/merchant/form";
    }

    /**
     * 添加商家
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    private Map<String, Object> create(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @ModelAttribute WebUser merchant) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be ajax !");
            }

            merchantApplication.createMerchant(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "添加商家账号" + merchant.getUsername(), Securitys.getIp(request));

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[添加商家异常]", e);
            return ImmutableMap.of("status", false, "message", "添加商家异常");
        }

        return ImmutableMap.of("status", true);
    }

    /**
     * 编辑商家信息
     *
     * @param id 商家id
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.GET)
    private String modify(Model model, @PathVariable("id") long id) {

        WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

        List<MerchantGoodsChannel> goodsChannels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(id), MerchantGoodsChannel.class);
        List<String> channelNames = goodsChannels.stream().map(c -> c.getChannel().getName()).collect(Collectors.toList());

        model.addAttribute("merchant", merchant).addAttribute("channels", queryChannelService.findAll(QGoodsChannel.goodsChannel.status.eq(1).and(QGoodsChannel.goodsChannel.level.eq(1).and(QGoodsChannel.goodsChannel.deleteStatus.eq(0))), GoodsChannel.class)).addAttribute("channelNames", channelNames).addAttribute("_method", "PUT");

        return "mall/merchant/form";
    }

    /**
     * 编辑商家信息
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> modify(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @ModelAttribute WebUser merchant) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be ajax !");
            }

            merchantApplication.modifyMerchant(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "编辑商家账号" + merchant.getUsername(), Securitys.getIp(request));

        } catch (IllegalArgumentException e) {
            return ImmutableMap.of("status", false, "message", e.getMessage());
        } catch (Exception e) {
            log.error("[编辑商家异常]", e);
            return ImmutableMap.of("status", false, "message", "编辑商家异常");
        }

        return ImmutableMap.of("status", true);
    }

    /**
     * 禁用
     */
    @RequestMapping(value = "/disable", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> disable(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            merchantApplication.disable(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "禁止商家登录账号" + merchant.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 启用
     */
    @RequestMapping(value = "/enabled", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> enabled(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            merchantApplication.enabled(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "允许商家登录账号" + merchant.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 设为自营商家
     */
    @RequestMapping(value = "/selfSupport", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> selfSupport(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            merchantApplication.selfSupport(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "设置成为自营商家" + merchant.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 取消自营
     */
    @RequestMapping(value = "/cancelSelfSupport", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> cancelSelfSupport(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            merchantApplication.cancelSelfSupport(merchant);
            logApplication.eventOfSystem(Securitys.currentUser(), "取消自营商家" + merchant.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 批量禁用
     */
    @RequestMapping(value = "/disables", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> disables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("ids") String data) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            List<Long> ids = Splitter.on(";").omitEmptyStrings().trimResults().splitToList(data).stream().map(Long::valueOf).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(ids)) {
                merchantApplication.disables(queryChannelService.findAll(QWebUser.webUser.id.in(ids), WebUser.class));
                logApplication.eventOfSystem(Securitys.currentUser(), "批量禁止商家登录账号", Securitys.getIp(request));
            }

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[禁用商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 批量启用
     */
    @RequestMapping(value = "/enables", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> enables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("ids") String data) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            List<Long> ids = Splitter.on(";").omitEmptyStrings().trimResults().splitToList(data).stream().map(Long::valueOf).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(ids)) {
                merchantApplication.enables(queryChannelService.findAll(QWebUser.webUser.id.in(ids), WebUser.class));
                logApplication.eventOfSystem(Securitys.currentUser(), "批量允许商家登录账号", Securitys.getIp(request));
            }

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[启用商家异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 重置密码
     */
    @RequestMapping(value = "/resetPassword", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> resetPassword(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, WebUser params) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser merchant = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);

            merchantApplication.modifyPassword(merchant, MD5HashUtils.MD5("123456"));

            logApplication.eventOfSystem(Securitys.currentUser(), "重置商家密码" + merchant.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[重置会员密码异常]", e);
            return ImmutableMap.of("status", false);
        }
    }


    /**
     * 条件查询
     */
    private String builderSQL(String sql, Map<String, Object> params, WebUser merchant) {

        if (!Strings.isNullOrEmpty(merchant.getRealName())) {
            sql += " and u.realName like :realname ";
            params.put("realname", "%" + merchant.getRealName() + "%");
        }

        if (!Strings.isNullOrEmpty(merchant.getMobile())) {
            sql += " and u.mobile like :mobile ";
            params.put("mobile", "%" + merchant.getMobile() + "%");
        }

        if (!Strings.isNullOrEmpty(merchant.getUsername())) {
            sql += " and u.username like :username ";
            params.put("username", "%" + merchant.getUsername() + "%");
        }

        if (!Strings.isNullOrEmpty(merchant.getShopName())) {
            sql += " and u.shopName like :shopname ";
            params.put("shopname", "%" + merchant.getShopName() + "%");
        }

        if (merchant.getMainType() > 0) {
            sql += " and u.mainType = :maintype ";
            params.put("maintype", merchant.getMainType());
        }

        if (!Strings.isNullOrEmpty(merchant.getOrderByGoodsNumber())) {
            sql += " order by u.goodsNumber " + merchant.getOrderByGoodsNumber();
        }

        if (!Strings.isNullOrEmpty(merchant.getOrderByMerchantEnterTime())) {
            sql += " order by u.merchantEnterTime " + merchant.getOrderByMerchantEnterTime();
        }

        if (!Strings.isNullOrEmpty(merchant.getOrderByTotalOrderAmount())) {
            sql += " order by u.totalOrderAmount " + merchant.getOrderByTotalOrderAmount();
        }

        if (!Strings.isNullOrEmpty(merchant.getOrderByTotalOrderNumber())) {
            sql += " order by u.totalOrderNumber " + merchant.getOrderByTotalOrderNumber();
        }

        return sql;
    }


}
